package com.ytd.common.base;

import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkRequest;
import android.os.Build;
import android.os.Process;

import androidx.annotation.NonNull;

import com.hjq.language.MultiLanguages;
import com.hjq.language.OnLanguageListener;
import com.jakewharton.processphoenix.ProcessPhoenix;
import com.tencent.bugly.crashreport.CrashReport;
import com.ytd.common.net.SocketManager;
import com.ytd.common.util.FileUtils;
import com.ytd.common.util.LogUtil;
import com.ytd.common.util.NetUtil;
import com.ytd.common.util.ToastUtil;
import com.ytd.common.util.YtdConfig;

import java.util.Arrays;
import java.util.Locale;
import java.util.Map;

/**
 * Your class notes
 *
 * @author gaoguanchao
 * @since 2023/4/14
 */
public class BaseApplication extends Application {
    private static Context context;//上下文
    /**
     * 当前网络离线
     */
    private boolean isOffline;

    /**
     * 是否进入网络离线等待状态   不等待。直接离线处理数据。等待 弹窗
     */
    private boolean isOfflineWait;

    private boolean isNetworkAvailable;

    private static BaseApplication instance;

    public static BaseApplication getInstance() {
        return instance;
    }

//    public static final int CRASHTYPE_JAVA_CRASH = 0; // Java crash
//    public static final int CRASHTYPE_JAVA_CATCH = 1; // Java caught exception
//    public static final int CRASHTYPE_NATIVE = 2; // Native crash
//    public static final int CRASHTYPE_U3D = 3; // Unity error
//    public static final int CRASHTYPE_ANR = 4; // ANR
//    public static final int CRASHTYPE_COCOS2DX_JS = 5; // Cocos JS error
//    public static final int CRASHTYPE_COCOS2DX_LUA = 6; // Cocos Lua error

    @Override
    protected void attachBaseContext(Context base) {
        // 绑定语种
        super.attachBaseContext(MultiLanguages.attach(base));
    }

    @Override
    public void onCreate() {
        super.onCreate();
        instance = this;
        context = getApplicationContext();

        // 初始化语种切换框架
        MultiLanguages.init(this);

        // 设置语种变化监听器
        MultiLanguages.setOnLanguageListener(new OnLanguageListener() {

            @Override
            public void onAppLocaleChange(Locale oldLocale, Locale newLocale) {
                LogUtil.d("MultiLanguages", "onAppLocaleChange，旧语种：" + oldLocale + "，新语种：" + newLocale);
                onLocaleChange(oldLocale, newLocale);
            }

            @Override
            public void onSystemLocaleChange(Locale oldLocale, Locale newLocale) {
                LogUtil.d("MultiLanguages",
                    "onSystemLocaleChange，旧语种：" + oldLocale + "，新语种：" + newLocale + "，是否跟随系统：" +
                        MultiLanguages.isSystemLanguage(instance));
                onAppSystemLocaleChange(oldLocale, newLocale);
            }
        });

        FileUtils.init(context);
        ToastUtil.init(context);
        LogUtil.deleteLOG();
        ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

        connectivityManager.requestNetwork(new NetworkRequest.Builder().build(),
            new ConnectivityManager.NetworkCallback() {
                @Override
                public void onAvailable(Network network) {
                    super.onAvailable(network);
                    onNetworkAvailable();
                    isNetworkAvailable = true;
                }

                @Override
                public void onLost(@NonNull Network network) {
                    super.onLost(network);
                    onNetworkLost();
                    isNetworkAvailable = false;
                }
            });
        LogUtil.d("当前商户：" + YtdConfig.getMerchantName());
        LogUtil.d("ABIS：" + Arrays.toString(Build.SUPPORTED_ABIS));
    }

    private void onAppSystemLocaleChange(Locale oldLocale, Locale newLocale) {

    }

    protected void onLocaleChange(Locale oldLocale, Locale newLocale) {

    }

    protected void onNetworkLost() {
        LogUtil.d("NetworkCallback onLost");
        SocketManager.getInstance().networkOffline();
    }

    protected void onNetworkAvailable() {
        LogUtil.d("NetworkCallback onAvailable");
        boolean connect = SocketManager.getInstance().isConnect();
        if (!connect) {
            SocketManager.getInstance().reconnectSocket();
        }
    }

    public static Context getContext() {
        return context;
    }

    public boolean isOffline() {
        return isOffline;
    }

    public void setOffline(boolean offline) {
        isOffline = offline;
    }

    public boolean isOfflineWait() {
        return isOfflineWait;
    }

    public void setOfflineWait(boolean offlineWait) {
        isOfflineWait = offlineWait;
    }

    public boolean isLocalMode() {
        return isOffline && !isOfflineWait;
    }

    public boolean isNetworkAvailable() {
        return isNetworkAvailable || NetUtil.isNetworkAvailable(this);
    }


    protected CrashReport.UserStrategy getCrashHandleCallback() {
        CrashReport.UserStrategy strategy = new CrashReport.UserStrategy(this);
        strategy.setCrashHandleCallback(new CrashReport.CrashHandleCallback() {
            public Map<String, String> onCrashHandleStart(int crashType, String errorType,
                                                          String errorMessage, String errorStack) {
                LogUtil.d("onCrashHandleStart");
                LogUtil.crashHandlerLog(errorMessage);
                LogUtil.crashHandlerLog(errorStack);
                restart(crashType);
                return null;
            }

            @Override
            public byte[] onCrashHandleStart2GetExtraDatas(int crashType, String errorType,
                                                           String errorMessage, String errorStack) {
                LogUtil.d("onCrashHandleStart2GetExtraDatas");
                try {
                    return "Extra data.".getBytes("UTF-8");
                } catch (Exception e) {
                    return null;
                }
            }

        });
        return strategy;
    }

    public void restart(int level) {
        LogUtil.crashHandlerLog("------------------程序" + level + "异常-----------------------------");
        LogUtil.crashHandlerLog("------------------程序自启动-----------------------------");
        restart();
    }

    public static void restart() {
        try {
            Intent restart =
                new Intent(instance.getPackageManager().getLaunchIntentForPackage(instance.getPackageName()));
            restart.addFlags(
                Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK);
            restart.setAction("restart");
            instance.startActivity(restart);
            Process.killProcess(Process.myPid());
            System.exit(0);
        } catch (Throwable e) {
            LogUtil.crashHandlerLog("------------------自启动失败-----------------------------");
            ProcessPhoenix.triggerRebirth(instance);
        }
    }
}
